package net.zubara.esni.ui.view;

import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeMap;
import java.util.Map.Entry;

import net.zubara.esni.core.client.FacebookClient;
import net.zubara.esni.core.client.XMLRemoteResponseDeserializer;
import net.zubara.esni.core.json.JSONObject;
import net.zubara.esni.core.pojo.IFriendList;
import net.zubara.esni.core.pojo.StatusGetResponse;
import net.zubara.esni.core.util.CoreUtil;
import net.zubara.esni.ui.UIMessages;

import org.eclipse.ecf.core.IContainer;
import org.eclipse.ecf.remoteservice.IRemoteService;
import org.eclipse.ecf.remoteservice.IRemoteServiceRegistration;
import org.eclipse.ecf.remoteservice.client.IRemoteCallParameter;
import org.eclipse.ecf.remoteservice.client.IRemoteCallable;
import org.eclipse.ecf.remoteservice.client.IRemoteServiceClientContainerAdapter;
import org.eclipse.ecf.remoteservice.client.RemoteCallParameter;
import org.eclipse.ecf.remoteservice.rest.IRestCall;
import org.eclipse.ecf.remoteservice.rest.RestCallFactory;
import org.eclipse.ecf.remoteservice.rest.RestCallableFactory;
import org.eclipse.equinox.concurrent.future.IFuture;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;

@SuppressWarnings("restriction")
public class BaseView extends ViewPart {

	public static final String VIEW_ID = "net.zubara.esni.ui.view.BaseView"; //$NON-NLS-1$

	IContainer container;
	IRemoteServiceRegistration registration;
	String sessionKey;
	StyledText text;
	Browser browser;

	@Override
	public void createPartControl(Composite parent) {
		Composite c = new Composite(parent, SWT.NONE);
		c.setLayout(new GridLayout());
		GridData cGd = new GridData();
		c.setLayoutData(cGd);

		browser = new Browser(c, SWT.BORDER);
		GridData browserGd = GridDataFactory.fillDefaults().grab(true, false).create();
		browserGd.heightHint = 60;
		browser.setLayoutData(browserGd);
		browser.setUrl(FacebookClient.AUTHENTICATION_URL);

		Button b = new Button(c, SWT.PUSH);
		b.setText(UIMessages.BaseView_CallMethod);

		text = new StyledText(c, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
		text.setEditable(false);
		Font font = new Font(PlatformUI.getWorkbench().getDisplay(), "Courier New", 10, SWT.NORMAL); //$NON-NLS-1$
		text.setFont(font);
		GridData textGd = GridDataFactory.fillDefaults().grab(true, true).create();
		text.setLayoutData(textGd);

		b.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				super.widgetSelected(event);
				try {
					// Get adapter
					IRemoteServiceClientContainerAdapter adapter = (IRemoteServiceClientContainerAdapter) container
							.getAdapter(IRemoteServiceClientContainerAdapter.class);
					// Setup resource handler
					adapter.setResponseDeserializer(new XMLRemoteResponseDeserializer());

					// Create and register callable to register service
					List<IRemoteCallParameter> params = new ArrayList<IRemoteCallParameter>();
					TreeMap<String, String> tm = new TreeMap<String, String>();
					tm.put("method", "status.get");
					tm.put("api_key", "92c404cec3bf1e0240051bfa7d3850cd");
					tm.put("format", "xml");
					tm.put("v", "1.0");
					tm.put("call_id", String.valueOf(System.currentTimeMillis()));

					String url = browser.getUrl();

					String jsonString = url.substring(url.indexOf("?") + 1, url.indexOf("&"));
					jsonString = URLDecoder.decode(jsonString, "UTF-8");
					jsonString = "{" + jsonString + "}";

					JSONObject s = new JSONObject(jsonString).getJSONObject("session");

					tm.put("session_key", s.getString("session_key"));
					// tm.put("uid", s.getString("uid"));

					StringBuilder sb = new StringBuilder();
					for (Entry<String, String> entry : tm.entrySet()) {
						sb.append(entry.getKey());
						sb.append("=");
						sb.append(entry.getValue());
						params.add(createParameter(entry.getKey(), entry.getValue()));
					}
					// sb.append("f2b8d9f706b92aae395822242937c253");
					sb.append(s.getString("secret"));
					String sig = CoreUtil.generateMd5(sb.toString());
					params.add(createParameter("sig", sig));
					IRemoteCallParameter[] p1 = params.toArray(new IRemoteCallParameter[0]);
					// Setup callable
					IRemoteCallable c1 = RestCallableFactory.createCallable("getStatuses", "/restserver.php", p1);
					String[] serviceInterfaceNames = new String[] { StatusGetResponse.class.getName() };
					IRemoteCallable[][] remoteCallables = new IRemoteCallable[][] { { c1 } };
					registration = adapter.registerCallables(serviceInterfaceNames, remoteCallables, null);

					callAsync();

				} catch (Exception e1) {
					e1.printStackTrace();
				}
			}
		});
	}

	@Override
	public void setFocus() {

	}

	public Object callSync() {
		// Get adapter
		IRemoteServiceClientContainerAdapter adapter = (IRemoteServiceClientContainerAdapter) container
				.getAdapter(IRemoteServiceClientContainerAdapter.class);
		IRemoteService restClientService = adapter.getRemoteService(registration.getReference());
		try {
			Object result = restClientService.callSync(RestCallFactory.createRestCall(IFriendList.class.getName() + ".getFriends")); //$NON-NLS-1$
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	@SuppressWarnings("restriction")
	public Object callAsync() {
		// Get adapter
		IRemoteServiceClientContainerAdapter adapter = (IRemoteServiceClientContainerAdapter) container
				.getAdapter(IRemoteServiceClientContainerAdapter.class);
		IRemoteService restClientService = adapter.getRemoteService(registration.getReference());
		try {
			IRestCall restCall = RestCallFactory.createRestCall(StatusGetResponse.class.getName() + ".getStatuses"); //$NON-NLS-1$
			IFuture future = restClientService.callAsync(restCall);
			Object result = future.get();
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	private IRemoteCallParameter createParameter(String name, String value) {
		return new RemoteCallParameter(name, value);
	}

}
